package com.pureut.storage.service.impl;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.utils.bean.BeanUtils;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.storage.domain.*;
import com.pureut.storage.domain.system.domain.SysDocument;
import com.pureut.storage.dto.*;
import com.pureut.storage.export.AllotManagementExport;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.*;
import com.pureut.storage.vo.*;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.QualityFeginService;
import com.pureut.system.api.RemoteUserService;
import com.pureut.system.api.SystemDocumentFeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.domain.SysUser;
import com.pureut.system.api.vo.QualitySchemeConfigurationVo;
import com.pureut.system.api.vo.MaterialNumberAndBatchNoVo;
import com.pureut.system.api.vo.QualityInspectionDocumentVo;
import com.pureut.system.api.vo.UpdateQualityStatusVo;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: CM
 * @date: 2023/1/10  21:31
 */
@Service
public class AllotManagementServiceImpl extends ServiceImpl<AllotManagementMapper, AllotManagement> implements AllotManagementService {

    @Resource
    private AllotManagementMapper allotManagementMapper;

    @Resource
    private WarehouseMapper warehouseMapper;

    @Resource
    private PublicGoodsMapper publicGoodsMapper;

    @Resource
    private WmsStockInfoMapper wmsStockInfoMapper;

    @Resource
    private AllotManagementDetailMapper allotManagementDetailMapper;

    //单据配置
    @Resource
    private SystemDocumentFeignService systemDocumentFeignService;

    @Resource
    private RemoteUserService remoteUserService;

    @Resource
    private WarehouseService warehouseService;

    @Resource
    private FeignService feignService;

    @Resource
    private AllotManagementDetailService allotManagementDetailService;

    //拣货提示
    @Resource
    private PickingSchemeService pickingSchemeService;


    @Resource
    private WmsStockInfoService wmsStockInfoService;

    @Resource
    private QualityFeginService qualityFeginService;

    @Lazy
    @Resource
    ProductionPickingService productionPickingService;

    /**
     * 新增调拨单
     *
     * @param allotManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addAllot(AllotManagementVo allotManagementVo) throws Exception {

        //获取明细
        List<AllotManagementListVo> list = allotManagementVo.getList();
        if (list.size() == 0) {
            throw new GlobalException("至少添加一条明细");
        }

        List<AllotManagement> list1 = new ArrayList<>();
        for (AllotManagementListVo allotManagementListVo : list) {

            String sn = feignService.getAuthorityCoding("warehouse:inside:transfer:list");
            if (sn == null) {
                throw new GlobalException("该单据未进行配置,无法生成单据编码");
            }

            AllotManagement allotManagement = new AllotManagement();
            BeanUtils.copyProperties(allotManagementVo, allotManagement);
            BeanUtils.copyProperties(allotManagementListVo, allotManagement);
            allotManagement.setAllotTraniveType(Integer.valueOf(allotManagementVo.getAllotTraniveType()));
            //设置调拨单号
            allotManagement.setAllotDoc(sn);
            //设置单据状态
            allotManagement.setAllotStatus(1);
            allotManagement.setDeptId(SecurityUtils.getDeptId());
            //设置开单人
            allotManagement.setCreateUser(SecurityUtils.getUsername());
            //设置开单时间
            allotManagement.setCreateTime(new Date());
            list1.add(allotManagement);
        }
        return saveBatch(list1);
    }

    /**
     * 调拨列表
     *
     * @param allotManagementVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<AllotManagementDto> getList(AllotManagementVo allotManagementVo) {
        List<AllotManagementDto> allotManagementDtos = allotManagementMapper.selecAllottList(allotManagementVo);

        //获取单据状态字典数据
        List<SysDictData> statusArray = DictUtils.getDictCache("allot_management_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出收发类型
        List<SysDictData> receivType = DictUtils.getDictCache("allot_management_type");
        Map<String, String> typeMap = receivType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出单位
        List<SysDictData> unitList = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));


//        List<AllotManagementDto> list = new ArrayList<>();

        for (AllotManagementDto allotManagementDto : allotManagementDtos) {
            //单据状态
            allotManagementDto.setAllotStatusDict(allotManagementDto.getAllotStatus());
            allotManagementDto.setAllotStatus(statusMap.get(allotManagementDto.getAllotStatus()));
            //收发类型
            allotManagementDto.setAllotTraniveTypeDict(allotManagementDto.getAllotTraniveType());
            allotManagementDto.setAllotTraniveType(typeMap.get(allotManagementDto.getAllotTraniveType()));

            //单位
            String materialUnit = allotManagementDto.getMaterialUnit();
            allotManagementDto.setMaterialUnit(unitMap.get(materialUnit));

            String allotWarehourseIn = allotManagementDto.getAllotWarehourseIn();
            Warehouse warehouse = warehouseMapper.selectById(Long.parseLong(allotWarehourseIn));
            if (warehouse != null) {
                allotManagementDto.setAllotWarehourseIn(warehouse.getWarehouseName());
            }

            String allotWarehourseOut = allotManagementDto.getAllotWarehourseOut();
            Warehouse warehouse1 = warehouseMapper.selectById(Long.parseLong(allotWarehourseOut));
            if (warehouse1 != null) {
                allotManagementDto.setAllotWarehourseOut(warehouse1.getWarehouseName());
            }
//            list.add(allotManagementDto);

        }
        return allotManagementDtos;
    }

    /**
     * 修改调拨单
     *
     * @param allotManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAllot(AllotManagementVo allotManagementVo) {

        //根据id查出当前修改的明细
        AllotManagement allotManagement = getById(allotManagementVo.getId());
        //获取状态
        int allotStatus = allotManagement.getAllotStatus();
        if (allotStatus != 1) {
            throw new GlobalException("只能修改状态为待出库的单据");
        }
        //调拨日期
        allotManagement.setAllotDate(allotManagementVo.getAllotDate());
        //收发类型
        allotManagement.setAllotTraniveType(Integer.parseInt(allotManagementVo.getAllotTraniveType()));
        //备注
        allotManagement.setRemark(allotManagementVo.getRemark());
        //计划出库量
        allotManagement.setAllotAmount(allotManagementVo.getList().get(0).getAllotAmount());
        //调出仓库
        allotManagement.setAllotWarehourseOut(allotManagementVo.getList().get(0).getAllotWarehourseOut());
        //调入仓库
        allotManagement.setAllotWarehourseIn(allotManagementVo.getList().get(0).getAllotWarehourseIn());

        return updateById(allotManagement);
    }

    /**
     * 查看调拨单
     *
     * @param id
     * @return
     */
    @Override
    public AllotManagementDto view(Long id) {

        AllotManagement allotManagement = getById(id);

        //获取单据状态字典数据
        List<SysDictData> statusArray = DictUtils.getDictCache("allot_management_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出收发类型
        List<SysDictData> receivType = DictUtils.getDictCache("allot_management_type");
        Map<String, String> typeMap = receivType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //根据字典查出单位
        List<SysDictData> unitList = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        AllotManagementDto allotManagementDto = new AllotManagementDto();
        allotManagementDto.setId(allotManagement.getId());
        //单据状态
        allotManagementDto.setAllotStatusDict(allotManagement.getAllotStatus() + "");
        allotManagementDto.setCloseCause(allotManagement.getCloseCause());
        allotManagementDto.setAllotStatus(statusMap.get(allotManagement.getAllotStatus() + ""));
        //收发类型
        allotManagementDto.setAllotTraniveType(allotManagement.getAllotTraniveType() + "");
        allotManagementDto.setAllotTraniveTypeDict(typeMap.get(allotManagement.getAllotTraniveType() + ""));

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, allotManagement.getAllotItemCode()));

        //单位
        String materialUnit = publicGoods.getMaterialUnit();
        allotManagementDto.setMaterialUnit(unitMap.get(materialUnit));

        allotManagementDto.setMaterialName(publicGoods.getMaterialName());
        allotManagementDto.setMaterialSpec(publicGoods.getMaterialSpec());

        //调拨单号
        allotManagementDto.setAllotDoc(allotManagement.getAllotDoc());
        //调拨日期
        allotManagementDto.setAllotDate(allotManagement.getAllotDate());
        //备注
        allotManagementDto.setRemark(allotManagement.getRemark());

        String allotWarehourseIn = allotManagement.getAllotWarehourseIn();
//        Warehouse warehouse = warehouseMapper.selectById(Long.parseLong(allotWarehourseIn));
//        allotManagementDto.setAllotWarehourseIn(warehouse.getWarehouseName());
        String allotWarehourseOut = allotManagement.getAllotWarehourseOut();
//        Warehouse warehouse1 = warehouseMapper.selectById(Long.parseLong(allotWarehourseOut));
//        allotManagementDto.setAllotWarehourseOut(warehouse1.getWarehouseName());

        List<AllotManagementDetailViewDto> list = new ArrayList<>();
        AllotManagementDetailViewDto allotManagementDetailViewDto = new AllotManagementDetailViewDto();
        allotManagementDetailViewDto.setAllotItemCode(allotManagement.getAllotItemCode());
        allotManagementDetailViewDto.setMaterialName(publicGoods.getMaterialName());
        allotManagementDetailViewDto.setMaterialSpec(publicGoods.getMaterialSpec());
        allotManagementDetailViewDto.setAllotUnit(allotManagement.getAllotUnit());
        allotManagementDetailViewDto.setMaterialUnitDict(unitMap.get(materialUnit));
        allotManagementDetailViewDto.setAllotAmount(allotManagement.getAllotAmount());
        allotManagementDetailViewDto.setAllotWeightOut(allotManagement.getAllotWeightOut());
        //allotManagementDetailViewDto.setAllotWarehourseOut(allotManagement.getAllotWarehourseOut());
        //allotManagementDetailViewDto.setAllotWarehourseIn(allotManagement.getAllotWarehourseIn());
//        allotManagementDetailViewDto.setAllotWarehourseInName(warehouse.getWarehouseName());
        allotManagementDetailViewDto.setAllotWarehourseIn(allotWarehourseIn);

        allotManagementDetailViewDto.setAllotWarehourseOut(allotWarehourseOut);
//        allotManagementDetailViewDto.setAllotWarehourseOutName(warehouse1.getWarehouseName());

        list.add(allotManagementDetailViewDto);

        allotManagementDto.setList(list);

        return allotManagementDto;
    }

    /**
     * 删除单据
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAllot(String ids) {
        //将ids根据逗号拆分成数组
        List<String> idStr = Arrays.asList(ids.split(","));
        if (idStr.size() == 0) {
            throw new GlobalException("请至少勾选一条单据");
        }
        List<AllotManagement> allotManagements = allotManagementMapper.selectBatchIds(idStr);
        for (AllotManagement allotManagement : allotManagements) {
            int allotStatus = allotManagement.getAllotStatus();
            if (allotStatus != 1) {
                throw new GlobalException("只能删除待出库状态的单据");
            }
        }
        return allotManagementMapper.deleteBatchIds(idStr) > 0;
    }

    /**
     * 关结单据
     *
     * @param allotManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean closeAllot(AllotManagementVo allotManagementVo) {
        if (allotManagementVo.getId() == null) {
            throw new GlobalException("至少勾选择一条单据进行关结");
        }
        AllotManagement allotManagement = allotManagementMapper.selectById(allotManagementVo.getId());
        int allotStatus = allotManagement.getAllotStatus();

        try {
            //如果检验单状态是出库中，待检验，待交接，待入库，入库中条码在库存中恢复，待检验品质检验单更新为已撤销
            if (allotStatus == 2 || allotStatus == 6 || allotStatus == 7 || allotStatus == 3 || allotStatus == 4) {
                //根据单号获取生产领料单明细
                List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                ArrayList<WmsStockInfo> wmsStockInfos = new ArrayList<>();

                for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                    WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotManagementDetail.getMaterialNumber()));
                    wmsStockInfo.setWsiMaterialStatus(2);
                    wmsStockInfos.add(wmsStockInfo);
                }

                boolean b = wmsStockInfoService.updateBatchById(wmsStockInfos);


                if (allotStatus == 6) {
                    //如果是待检验修改品质检验单
                    UpdateQualityStatusVo updateQualityStatusVo = new UpdateQualityStatusVo();
                    updateQualityStatusVo.setStatus(8);
                    updateQualityStatusVo.setAssociatedNo(allotManagement.getAllotDoc());
                    AjaxResult ajaxResult = qualityFeginService.updateQualityInspectionDocument(updateQualityStatusVo);


                    if (!"200".equals(ajaxResult.get("code").toString())) {
                        throw new GlobalException("服务调用失败");
                    }

                }
            }
        } catch (Exception e) {
            throw new GlobalException("关结失败");
        }

        //查出交接人
        String closeUser = allotManagement.getCloseUser();

        if (closeUser == null) {
            closeUser = SecurityUtils.getUsername();
        } else {
            closeUser = closeUser + "," + SecurityUtils.getUsername();
        }

        allotManagement.setCloseCause(allotManagementVo.getCloseCause());
        allotManagement.setCloseTime(new Date());
        allotManagement.setCloseUser(closeUser);
        allotManagement.setAllotStatus(8);
        return updateById(allotManagement);
    }

    /**
     * 导出
     *
     * @param allotManagementVo
     * @return
     */
    @Override
    public List<AllotManagementExport> getInfoExport(AllotManagementVo allotManagementVo) {
        if (allotManagementVo.getIdStr() != null) {
            List<String> idList = Arrays.asList(allotManagementVo.getIdStr().split(","));

            allotManagementVo.setIds(idList);
        }
        List<AllotManagementExport> list = allotManagementMapper.getInfoExport(allotManagementVo);


        //根据字典查出收发类型
        List<SysDictData> receivType = DictUtils.getDictCache("allot_management_type");
        Map<String, String> typeMap = receivType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (AllotManagementExport allotManagementExport : list) {
            allotManagementExport.setAllotTraniveType(typeMap.get(allotManagementExport.getAllotTraniveType()));
        }

        return list;
    }

    /**
     * Pda调拨单列表
     *
     * @param allotPdaListVo
     * @return
     */
    @Override
    public List<AndroidPdaDto> allotPdaList(AllotPdaListVo allotPdaListVo) {
        allotPdaListVo.setDeptId(SecurityUtils.getDeptId());
        if (allotPdaListVo.getType() == 1) {
            //调拨出库
            return allotManagementMapper.getPdaList(allotPdaListVo);
        } else if (allotPdaListVo.getType() == 2) {
            //调拨入库
            return allotManagementMapper.getPdaList1(allotPdaListVo);
        } else if (allotPdaListVo.getType() == 3) {
            return allotManagementMapper.getPdaList3(allotPdaListVo);
        } else {
            return new ArrayList<>();
        }


    }

    @Override
    public AndroidPdaDto allotPdaView(AllotPdaListVo allotPdaListVo) {
        allotPdaListVo.setDeptId(SecurityUtils.getDeptId());
        if (allotPdaListVo.getType() == 1) {
            //调拨出库
            AndroidPdaDto pdaListView = allotManagementMapper.getPdaListView(allotPdaListVo);
            pdaListView.setType("调拨出库");
            SchemeVo schemeVo = new SchemeVo();
            schemeVo.setMaterialCode(pdaListView.getMaterialCode());
            schemeVo.setAssociatedDetails("5");
            pdaListView.setPickingPrompt(pickingSchemeService.getSchemeData(schemeVo).getCombinationName());
            return pdaListView;
        } else if (allotPdaListVo.getType() == 2) {
            //调拨入库
            AndroidPdaDto pdaListView = allotManagementMapper.getPdaListView1(allotPdaListVo);
            pdaListView.setType("调拨入库");
            SchemeVo schemeVo = new SchemeVo();
            schemeVo.setMaterialCode(pdaListView.getMaterialCode());
            schemeVo.setAssociatedDetails("5");
            pdaListView.setPickingPrompt(pickingSchemeService.getSchemeData(schemeVo).getCombinationName());
            return pdaListView;
        } else {
            return new AndroidPdaDto();
        }
    }

    /**
     * 品质检验回传检验结果
     *
     * @param updateDocVo
     * @return
     */
    @Override
    public boolean allotUpdateStatus(UpdateDocVo updateDocVo) {
        //获取菜单id
        Long menuId = feignService.getIdByMenuName("调拨管理");
        //交接方式
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        //交接方式
        int docHandoverMethod = sysDocument.getDocHandoverMark();

        //判断是否有交接

        //如果有交接，修改单据状态和物料明细状态为代交接
        if (docHandoverMethod == 1) {
            AllotManagement allotManagement = allotManagementMapper.selectOne(new QueryWrapper<AllotManagement>().lambda().eq(AllotManagement::getAllotDoc, updateDocVo.getDocNum()));
            allotManagement.setAllotStatus(7);//待交接
            updateById(allotManagement);
            List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, updateDocVo.getDocNum()));
            for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                allotManagementDetail.setMaterialStatus(3);//待交接
            }
            return allotManagementDetailService.updateBatchById(allotManagementDetailList);

        } else {
            AllotManagement allotManagement = allotManagementMapper.selectOne(new QueryWrapper<AllotManagement>().lambda().eq(AllotManagement::getAllotDoc, updateDocVo.getDocNum()));
            allotManagement.setAllotStatus(3);//待入库
            updateById(allotManagement);
            List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, updateDocVo.getDocNum()));
            for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                allotManagementDetail.setMaterialStatus(1);//已出库
            }
            return allotManagementDetailService.updateBatchById(allotManagementDetailList);
        }
    }

    /**
     * 拣货方案
     *
     * @param id
     * @return
     */
    @Override
    public SchemeDto point(Long id) {
        AllotManagement byId = getById(id);
        SchemeVo schemeVo = new SchemeVo();
        schemeVo.setMaterialCode(byId.getAllotItemCode());
        schemeVo.setAssociatedDetails("5");
        return pickingSchemeService.getSchemeData(schemeVo);
    }

    /**
     * 调拨出库
     *
     * @param allotDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AllotDbDto outAllot(AllotDbVo allotDbVo) throws Exception {
        String type = allotDbVo.getType();
        String step = allotDbVo.getStep();

        AllotDbDto allotDbDto = new AllotDbDto();

        //判断是否超收或者超发
        //获取菜单id
        Long menuId = feignService.getIdByMenuName("调拨管理");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);

        //根据字典查出单位
        List<SysDictData> unitList = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        AllotManagement byId = getById(allotDbVo.getId());

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, byId.getAllotItemCode()));

        //如果配置了送检,则校验是否配了检验方案
        if (sysDocument.getDocInspectionMark() == 1) {

            List<SysDocumentCheckDto> documentCheckDtoList = sysDocument.getDocumentCheckDtoList();
            if (documentCheckDtoList == null) {
                throw new GlobalException("请先在单据配置中配置送检方案");
            }

            QualitySchemeConfigurationVo qualitySchemeConfigurationVo = new QualitySchemeConfigurationVo();
            qualitySchemeConfigurationVo.setCategory(publicGoods.getMaterialCategory());
            qualitySchemeConfigurationVo.setItemRank(documentCheckDtoList.get(0).getCheckSubmit());
            qualitySchemeConfigurationVo.setMaterialCategory(publicGoods.getMaterialType());
            qualitySchemeConfigurationVo.setMaterialCode(byId.getAllotItemCode());
            boolean check = qualityFeginService.check(qualitySchemeConfigurationVo);

            if (!check) {
                throw new GlobalException("该物料不存在对应的检验方案");

            }
        }


        if (byId.getAllotStatus() != 1 && byId.getAllotStatus() != 2) {
            throw new GlobalException("只能对待出库或出库中状态的单据进行出库");
        }


        //如果是扫码出库
        if ("1".equals(type)) {

            WmsStockInfo wmsStockInfo1 = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotDbVo.getMaterialNumber()));
            if (wmsStockInfo1 == null) {
                throw new GlobalException("没有查询到该物料，请核实");
            }

            if (wmsStockInfo1.getWsiMaterialStatus() != 2) {
                throw new GlobalException("只能对在库的物料进行出库");
            }

            if ("1".equals(wmsStockInfo1.getWsiFreezeInfo())) {
                throw new GlobalException("该物料已冻结请重新输入");
            }

            //获取单据调出仓库
            String allotWarehourseOut = byId.getAllotWarehourseOut();
            boolean equals = allotWarehourseOut.equals(wmsStockInfo1.getWsiWarehourse());
            if (!equals) {
                throw new GlobalException("输入物料的仓库与单据仓库不一致,请核实");
            }

            //判断扫描到的物料编码是否和单据内需要的物料编码一致
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotDbVo.getMaterialNumber()));
            if (wmsStockInfo == null) {
                allotDbDto.setMessage("扫描失败，请核实后扫描");
                allotDbDto.setCode("500");
                return allotDbDto;
            }
            //扫描的物料编码
            String wsiMaterialCode = wmsStockInfo.getWsiMaterialCode();
            //根据物料编码在调拨单中查询是否存在
            AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());
            if (!allotManagement.getAllotItemCode().equals(wsiMaterialCode)) {
                allotDbDto.setMessage("扫描失败，请核实后扫描");
                allotDbDto.setCode("500");
                return allotDbDto;
            }

            //判断是否重复扫描
            AllotManagementDetail allotManagementDetail1 = allotManagementDetailMapper.selectOne(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

            if (allotManagementDetail1 != null) {
                allotDbDto.setMessage("请勿重复扫描");
                allotDbDto.setCode("500");
                return allotDbDto;
            }


            //出库数量
            Integer allotNumOut1 = allotManagement.getAllotNumOut();
            if (allotNumOut1 == null) {
                allotNumOut1 = 0;
            }
            allotManagement.setAllotNumOut(allotNumOut1 + 1);
            //状态改为出库中
            allotManagement.setAllotStatus(2);
            Double allotWeightOut1 = allotManagement.getAllotWeightOut();
            if (allotWeightOut1 == null) {
                allotWeightOut1 = 0.0;
            }
            BigDecimal bigDecimal = new BigDecimal(String.valueOf(allotWeightOut1));
            BigDecimal bigDecimal1 = new BigDecimal(wmsStockInfo.getWsiNetWeight());
            BigDecimal add = bigDecimal.add(bigDecimal1);

            //出库重量
            allotManagement.setAllotWeightOut(add.doubleValue());
            //修改实际量和数量
            updateById(allotManagement);

            //添加调拨物料明细
            AllotManagementDetail allotManagementDetail = new AllotManagementDetail();
            //添加物料号码
            allotManagementDetail.setMaterialNumber(wmsStockInfo.getWsiMaterialNumber());
            //添加物料状态(已出库)
            allotManagementDetail.setMaterialStatus(1);
            //添加物料关联单号
            allotManagementDetail.setAllotDoc(allotManagement.getAllotDoc());
            //添加物料编码
            allotManagementDetail.setMaterialCode(wmsStockInfo.getWsiMaterialCode());
            //毛重
            allotManagementDetail.setGrossWeight(wmsStockInfo.getWsiGorssWeight());
            //净重
            allotManagementDetail.setNetWeight(wmsStockInfo.getWsiNetWeight());
            //物料数量
            allotManagementDetail.setMaterialNum(wmsStockInfo.getWsiMaterialNum());
            //出库人
            allotManagementDetail.setDepositorOut(SecurityUtils.getUsername());
            //出库时间
            allotManagementDetail.setDeliveryTime(new Date());
            //出库仓储
            allotManagementDetail.setOutgoingStorage(wmsStockInfo.getWsiWarehourseInfo());
            //批次
            allotManagementDetail.setMaterialBatch(wmsStockInfo.getWsiMaterialBatch());

            //判断是否有检验
            int docInspectionMark = sysDocument.getDocInspectionMark();
            //如果有检验
            if (docInspectionMark == 1) {
                //修改单据明细为待检验
                allotManagementDetail.setMaterialStatus(4);
            } else {
                //判断是否有交接
                int docHandoverMark = sysDocument.getDocHandoverMark();
                //有交接
                if (docHandoverMark == 1) {
                    //修改单据明细为待交接
                    allotManagementDetail.setMaterialStatus(3);
                }
            }

            int insert = allotManagementDetailMapper.insert(allotManagementDetail);
            if (insert <= 0) {
                throw new GlobalException("出库失败");
            }


            AllotManagement allotManagement2 = allotManagementMapper.selectById(allotDbVo.getId());

            //判断单位是否是kg
            if ("2".equals(publicGoods.getMaterialUnit())) {
                //计划入库量等于重量
                allotManagement2.setAllotAmountIn(allotManagement2.getAllotWeightOut());
                //实际量
                allotManagement2.setAllotActual(allotManagement2.getAllotWeightOut());
            } else if ("3".equals(publicGoods.getMaterialUnit())) {
                //实际量
                BigDecimal dun = new BigDecimal("1000");
                BigDecimal outNum = new BigDecimal(String.valueOf(allotManagement2.getAllotWeightOut()));
                BigDecimal divide = outNum.divide(dun);

                //计划入库量等于重量
                allotManagement2.setAllotAmountIn(divide.doubleValue());
                //实际量
                allotManagement2.setAllotActual(divide.doubleValue());
            } else {
                //计划入库量==数量
                allotManagement2.setAllotAmountIn(Double.parseDouble(allotManagement2.getAllotNumOut() + ""));
                //实际量
                allotManagement2.setAllotActual(Double.parseDouble(allotManagement2.getAllotNumOut() + ""));
            }
            updateById(allotManagement2);


            //计划/实际
            allotDbDto.setPlanActual(allotManagement2.getAllotAmount() + "/" + allotManagement2.getAllotActual() + unitMap.get(publicGoods.getMaterialUnit()));
            allotDbDto.setAllotNumOut(allotManagement2.getAllotNumOut());
            allotDbDto.setCode("200");

            allotDbDto.setMessage("物料号码:" + allotDbVo.getMaterialNumber() + ",净重:" + wmsStockInfo.getWsiNetWeight() + ",数量:1" + "录入成功");

            //仓库状态更新为调拨
            wmsStockInfo.setWsiMaterialStatus(3);
            int i = wmsStockInfoMapper.updateById(wmsStockInfo);


            //查出调拨信息单
            AllotManagement allotManagement1 = allotManagementMapper.selectById(allotDbVo.getId());
            //判断是否有超收
            int docHairMark = sysDocument.getDocHairMark();
            //没有超收
            if (docHairMark != 1 && publicGoods.getMaterialHair() != 1) {

                //如果是kg
                if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
                    //计划出库重量
                    Double allotAmount = allotManagement1.getAllotAmount();
                    //实际出库重量
                    Double allotWeightOut = allotManagement1.getAllotWeightOut();
                    if (allotWeightOut >= allotAmount) {
                        //判断是否有检验或者交接
                        //判断是否有检验
                        int isDocInspectionMark = sysDocument.getDocInspectionMark();
                        //如果有检验
                        if (isDocInspectionMark == 1) {
                            //生成品质检验单
                            QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                            //添加类别，编码，物料类别
                            qualityInspectionDocumentVo.setMaterialCode(allotManagement1.getAllotItemCode());
                            qualityInspectionDocumentVo.setMaterialCategory(publicGoods.getMaterialType());
                            qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                            qualityInspectionDocumentVo.setAssociatedNo(allotManagement1.getAllotDoc());
                            qualityInspectionDocumentVo.setModeType(8);
                            List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNoVos = new ArrayList<>();
                            //查询当前明细表中的所有物料号码
                            List<AllotManagementDetail> allotManagementDetails = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                            String batchNum = "";

                            for (int j = 0; j < allotManagementDetails.size(); j++) {
                                if (j == 0) {
                                    batchNum = allotManagementDetails.get(j).getMaterialBatch();
                                } else {
                                    if (!batchNum.equals(allotManagementDetails.get(j).getMaterialBatch())) {
                                        batchNum = batchNum + "," + allotManagementDetails.get(j).getMaterialBatch();
                                    }
                                }

                                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                                materialNumberAndBatchNoVo.setMaterialNumber(allotManagementDetails.get(j).getMaterialNumber());
                                materialNumberAndBatchNoVo.setBatchNo(allotManagementDetails.get(j).getMaterialBatch());
                                materialNumberAndBatchNoVo.setMaterialCategory(publicGoods.getMaterialCategory());
                                materialNumberAndBatchNoVos.add(materialNumberAndBatchNoVo);
                            }
                            qualityInspectionDocumentVo.setBatchNo(batchNum);

                            productionPickingService.insertQuality(sysDocument, qualityInspectionDocumentVo, materialNumberAndBatchNoVos);
                            //修改单据明细为待检验
                            allotManagement1.setAllotStatus(6);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                        //判断是否有交接
                        int docHandoverMark = sysDocument.getDocHandoverMark();
                        //有交接
                        if (docHandoverMark == 1) {
                            //修改单据明细为待交接
                            allotManagement1.setAllotStatus(7);
                            allotManagementMapper.updateById(allotManagement1);

                        } else {
                            //修改单据状态为待入库
                            allotManagement1.setAllotStatus(3);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                    }
                } else {
                    //计划出库重量
                    double allotAmount = allotManagement1.getAllotAmount();
                    //实际出库数量
                    int allotNumOut = allotManagement1.getAllotNumOut();
                    if (allotNumOut >= allotAmount) {
                        //判断是否检验或者交接
                        //判断是否有检验
                        int isDocInspectionMark = sysDocument.getDocInspectionMark();
                        //如果有检验
                        if (isDocInspectionMark == 1) {
                            //生成品质检验单
                            QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                            //添加类别，编码，物料类别
                            qualityInspectionDocumentVo.setMaterialCode(allotManagement1.getAllotItemCode());
                            qualityInspectionDocumentVo.setMaterialCategory(publicGoods.getMaterialType());
                            qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                            qualityInspectionDocumentVo.setAssociatedNo(allotManagement1.getAllotDoc());
                            qualityInspectionDocumentVo.setModeType(8);
                            List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNoVos = new ArrayList<>();
                            //查询当前明细表中的所有物料号码
                            List<AllotManagementDetail> allotManagementDetails = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                            String batchNum = "";

                            for (int j = 0; j < allotManagementDetails.size(); j++) {
                                if (j == 0) {
                                    batchNum = allotManagementDetails.get(j).getMaterialBatch();
                                } else {
                                    if (!batchNum.equals(allotManagementDetails.get(j).getMaterialBatch())) {
                                        batchNum = batchNum + "," + allotManagementDetails.get(j).getMaterialBatch();
                                    }
                                }

                                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                                materialNumberAndBatchNoVo.setMaterialNumber(allotManagementDetails.get(j).getMaterialNumber());
                                materialNumberAndBatchNoVo.setBatchNo(allotManagementDetails.get(j).getMaterialBatch());
                                materialNumberAndBatchNoVo.setMaterialCategory(publicGoods.getMaterialCategory());
                                materialNumberAndBatchNoVos.add(materialNumberAndBatchNoVo);
                            }
                            qualityInspectionDocumentVo.setBatchNo(batchNum);

                            productionPickingService.insertQuality(sysDocument, qualityInspectionDocumentVo, materialNumberAndBatchNoVos);
                            //修改单据明细为待检验
                            allotManagement1.setAllotStatus(6);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                        //判断是否有交接
                        int docHandoverMark = sysDocument.getDocHandoverMark();
                        //有交接
                        if (docHandoverMark == 1) {
                            //修改单据明细为待交接
                            allotManagement1.setAllotStatus(7);
                            allotManagementMapper.updateById(allotManagement1);

                        } else {
                            //修改单据状态为待入库
                            allotManagement1.setAllotStatus(3);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                    }

                }
            }


            //如果是批次出库
        } else if ("2".equals(type)) {
            //判断扫描到的批号是否和单据内需要的批号一致
            List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, allotDbVo.getMaterialNumber()).eq(WmsStockInfo::getWsiMaterialStatus, '2').notIn(WmsStockInfo::getWsiFreezeInfo, 1));
            if (wmsStockInfoList.size() == 0) {
                throw new GlobalException("录入失败，请核实后再录入");
            }

            Double netWeight = wmsStockInfoMapper.getNetWeight(allotDbVo.getMaterialNumber());

            for (WmsStockInfo wmsStockInfo : wmsStockInfoList) {


                //扫描的物料编码
                String wsiMaterialCode = wmsStockInfo.getWsiMaterialCode();
                //根据物料编码在调拨单中查询是否存在
                AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());
                if (!allotManagement.getAllotItemCode().equals(wsiMaterialCode)) {
                    throw new GlobalException("录入失败，请核实后再录入");
                }

                //获取单据调出仓库
                String allotWarehourseOut = byId.getAllotWarehourseOut();
                boolean equals = allotWarehourseOut.equals(wmsStockInfo.getWsiWarehourse());
                if (!equals) {
                    throw new GlobalException("输入物料的仓库与单据仓库不一致,请核实");
                }


                //仓库状态更新为调拨
                wmsStockInfo.setWsiMaterialStatus(3);
                wmsStockInfoMapper.updateById(wmsStockInfo);

                Integer allotNumOut = allotManagement.getAllotNumOut();
                if (allotNumOut == null) {
                    allotNumOut = 0;
                }
                //出库数量
                allotManagement.setAllotNumOut(allotNumOut + 1);
                //状态改为出库中
                allotManagement.setAllotStatus(2);

                Double allotWeightOut = allotManagement.getAllotWeightOut();
                if (allotWeightOut == null) {
                    allotWeightOut = 0.0;
                }
                //原来的出库重量
                BigDecimal bigDecimal = new BigDecimal(String.valueOf(allotWeightOut));

                //新出库的重量
                BigDecimal bigDecimal1 = new BigDecimal(wmsStockInfo.getWsiNetWeight());

                BigDecimal add = bigDecimal.add(bigDecimal1);
                //出库重量
                allotManagement.setAllotWeightOut(add.doubleValue());

                //修改实际量和数量
                updateById(allotManagement);

                //添加调拨物料明细
                AllotManagementDetail allotManagementDetail = new AllotManagementDetail();
                //添加物料关联单号
                allotManagementDetail.setAllotDoc(allotManagement.getAllotDoc());
                //添加物料号码
                allotManagementDetail.setMaterialNumber(wmsStockInfo.getWsiMaterialNumber());
                //添加物料状态(已出库)
                allotManagementDetail.setMaterialStatus(1);
                //添加物料编码
                allotManagementDetail.setMaterialCode(wmsStockInfo.getWsiMaterialCode());
                //毛重
                allotManagementDetail.setGrossWeight(wmsStockInfo.getWsiGorssWeight());
                //净重
                allotManagementDetail.setNetWeight(wmsStockInfo.getWsiNetWeight());
                //物料数量
                allotManagementDetail.setMaterialNum(wmsStockInfo.getWsiMaterialNum());
                //出库人
                allotManagementDetail.setDepositorOut(SecurityUtils.getUsername());
                //出库时间
                allotManagementDetail.setDeliveryTime(new Date());
                //出库仓储
                allotManagementDetail.setOutgoingStorage(wmsStockInfo.getWsiWarehourseInfo());
                //批次
                allotManagementDetail.setMaterialBatch(wmsStockInfo.getWsiMaterialBatch());

                //判断是否有检验
                int docInspectionMark = sysDocument.getDocInspectionMark();
                //如果有检验
                if (docInspectionMark == 1) {
                    //修改单据明细为待检验
                    allotManagementDetail.setMaterialStatus(4);

                } else {
                    //判断是否有交接
                    int docHandoverMark = sysDocument.getDocHandoverMark();
                    //有交接
                    if (docHandoverMark == 1) {
                        //修改单据明细为待交接
                        allotManagementDetail.setMaterialStatus(3);
                    }
                }

                allotManagementDetailMapper.insert(allotManagementDetail);

            }
            //查出实际值,出库数量，计划量
            AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());


            //算出当前批次的总重量
            //WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialBatch, allotDbVo.getMaterialNumber()).eq(WmsStockInfo::getWsiMaterialStatus, 3).select(WmsStockInfo::getWsiNetWeight));


            //如果是kg
            if ("2".equals(publicGoods.getMaterialUnit())) {
                //计划入库重量则为出库重量
                allotManagement.setAllotAmountIn(allotManagement.getAllotWeightOut());
                allotManagement.setAllotActual(allotManagement.getAllotWeightOut());
            } else if ("3".equals(publicGoods.getMaterialUnit())) {
                //实际量
                BigDecimal dun = new BigDecimal("1000");
                BigDecimal outNum = new BigDecimal(allotManagement.getAllotWeightOut());
                BigDecimal divide = outNum.divide(dun);

                //计划入库重量则为出库重量
                allotManagement.setAllotAmountIn(divide.doubleValue());
                allotManagement.setAllotActual(divide.doubleValue());
            } else {
                int allotNumOut = allotManagement.getAllotNumOut();
                allotManagement.setAllotAmountIn(Double.parseDouble(allotNumOut + ""));
                allotManagement.setAllotActual(Double.parseDouble(allotNumOut + ""));
            }
            updateById(allotManagement);

            allotDbDto.setPlanActual(allotManagement.getAllotAmount() + "/" + allotManagement.getAllotActual() + publicGoods.getMaterialUnit());
            allotDbDto.setAllotNumOut(allotManagement.getAllotNumOut());


            //查出调拨信息单
            AllotManagement allotManagement1 = allotManagementMapper.selectById(allotDbVo.getId());
            //判断是否有超收
            int docHairMark = sysDocument.getDocHairMark();
            //超收
            if (docHairMark != 1 && publicGoods.getMaterialHair() != 1) {

                //如果是kg
                if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
                    //计划出库重量
                    double allotAmount = allotManagement1.getAllotAmount();
                    //实际出库重量
                    double allotWeightOut = allotManagement1.getAllotWeightOut();
                    if (allotWeightOut >= allotAmount) {
                        //判断是否有检验或者交接
                        //判断是否有检验
                        int isDocInspectionMark = sysDocument.getDocInspectionMark();
                        //如果有检验
                        if (isDocInspectionMark == 1) {
                            //生成品质检验单
                            QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                            //添加类别，编码，物料类别
                            qualityInspectionDocumentVo.setMaterialCode(allotManagement1.getAllotItemCode());
                            qualityInspectionDocumentVo.setMaterialCategory(publicGoods.getMaterialType());
                            qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                            qualityInspectionDocumentVo.setAssociatedNo(allotManagement1.getAllotDoc());
                            qualityInspectionDocumentVo.setModeType(8);
                            List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNoVos = new ArrayList<>();
                            //查询当前明细表中的所有物料号码
                            List<AllotManagementDetail> allotManagementDetails = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                            String batchNum = "";

                            for (int j = 0; j < allotManagementDetails.size(); j++) {
                                if (j == 0) {
                                    batchNum = allotManagementDetails.get(j).getMaterialBatch();
                                } else {
                                    if (!batchNum.equals(allotManagementDetails.get(j).getMaterialBatch())) {
                                        batchNum = batchNum + "," + allotManagementDetails.get(j).getMaterialBatch();
                                    }
                                }

                                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                                materialNumberAndBatchNoVo.setMaterialNumber(allotManagementDetails.get(j).getMaterialNumber());
                                materialNumberAndBatchNoVo.setBatchNo(allotManagementDetails.get(j).getMaterialBatch());
                                materialNumberAndBatchNoVo.setMaterialCategory(publicGoods.getMaterialCategory());
                                materialNumberAndBatchNoVos.add(materialNumberAndBatchNoVo);
                            }
                            qualityInspectionDocumentVo.setBatchNo(batchNum);

                            productionPickingService.insertQuality(sysDocument, qualityInspectionDocumentVo, materialNumberAndBatchNoVos);
                            //修改单据明细为待检验
                            allotManagement1.setAllotStatus(6);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                        //判断是否有交接
                        int docHandoverMark = sysDocument.getDocHandoverMark();
                        //有交接
                        if (docHandoverMark == 1) {
                            //修改单据明细为待交接
                            allotManagement1.setAllotStatus(7);
                            allotManagementMapper.updateById(allotManagement1);

                        } else {
                            //修改单据状态为待入库
                            allotManagement1.setAllotStatus(3);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                    }
                } else {
                    //计划出库重量
                    double allotAmount = allotManagement1.getAllotAmount();
                    //实际出库数量
                    int allotNumOut = allotManagement1.getAllotNumOut();
                    if (allotNumOut >= allotAmount) {
                        //判断是否检验或者交接
                        //判断是否有检验
                        int isDocInspectionMark = sysDocument.getDocInspectionMark();
                        //如果有检验
                        if (isDocInspectionMark == 1) {
                            //生成品质检验单
//生成品质检验单
                            QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                            //添加类别，编码，物料类别
                            qualityInspectionDocumentVo.setMaterialCode(allotManagement1.getAllotItemCode());
                            qualityInspectionDocumentVo.setMaterialCategory(publicGoods.getMaterialType());
                            qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
                            qualityInspectionDocumentVo.setAssociatedNo(allotManagement1.getAllotDoc());
                            qualityInspectionDocumentVo.setModeType(8);
                            List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNoVos = new ArrayList<>();
                            //查询当前明细表中的所有物料号码
                            List<AllotManagementDetail> allotManagementDetails = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                            String batchNum = "";

                            for (int j = 0; j < allotManagementDetails.size(); j++) {
                                if (j == 0) {
                                    batchNum = allotManagementDetails.get(j).getMaterialBatch();
                                } else {
                                    if (!batchNum.equals(allotManagementDetails.get(j).getMaterialBatch())) {
                                        batchNum = batchNum + "," + allotManagementDetails.get(j).getMaterialBatch();
                                    }
                                }

                                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                                materialNumberAndBatchNoVo.setMaterialNumber(allotManagementDetails.get(j).getMaterialNumber());
                                materialNumberAndBatchNoVo.setBatchNo(allotManagementDetails.get(j).getMaterialBatch());
                                materialNumberAndBatchNoVo.setMaterialCategory(publicGoods.getMaterialCategory());
                                materialNumberAndBatchNoVos.add(materialNumberAndBatchNoVo);
                            }
                            qualityInspectionDocumentVo.setBatchNo(batchNum);

                            productionPickingService.insertQuality(sysDocument, qualityInspectionDocumentVo, materialNumberAndBatchNoVos);
                            //修改单据明细为待检验
                            allotManagement1.setAllotStatus(6);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                        //判断是否有交接
                        int docHandoverMark = sysDocument.getDocHandoverMark();
                        //有交接
                        if (docHandoverMark == 1) {
                            //修改单据明细为待交接
                            allotManagement1.setAllotStatus(7);
                            allotManagementMapper.updateById(allotManagement1);

                        } else {
                            //修改单据状态为待入库
                            allotManagement1.setAllotStatus(3);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                    }

                }

            }
            allotDbDto.setCode("200");
            allotDbDto.setMessage("批次号:" + allotDbVo.getMaterialNumber() + "总净重:" + netWeight + "数量:" + wmsStockInfoList.size() + "录入成功");
        } else if ("3".equals(type)) {
            //条码撤销

            //在明细表里查是否为已经扫描过的，否则提示撤销失败
            AllotManagementDetail allotManagementDetail = allotManagementDetailMapper.selectOne(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getAllotDoc, byId.getAllotDoc()));
            if (allotManagementDetail == null) {
                allotDbDto.setMessage("撤销失败");
                allotDbDto.setCode("500");
                return allotDbDto;
            }
            //修改库存状态为在库
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotDbVo.getMaterialNumber()));
            wmsStockInfo.setWsiMaterialStatus(2);
            wmsStockInfoMapper.updateById(wmsStockInfo);
            //删除调拨明细
            int delete = allotManagementDetailMapper.delete(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getAllotDoc, byId.getAllotDoc()));
            //扣除重量
            AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());

            BigDecimal out = new BigDecimal(allotManagement.getAllotActual());
            BigDecimal bigDecimal = new BigDecimal(allotManagementDetail.getNetWeight());
            BigDecimal outWeight = out.subtract(bigDecimal);
            //修改出库重量
            allotManagement.setAllotWeightOut(outWeight.doubleValue());

            //扣除数量
            allotManagement.setAllotNumOut(allotManagement.getAllotNumOut() - 1);
            ////修改入库计划重量和实际出库重量
            if ("2".equals(publicGoods.getMaterialUnit())) {

                BigDecimal sj = new BigDecimal(String.valueOf(allotManagement.getAllotActual()));
                BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(allotManagementDetail.getNetWeight()));
                BigDecimal sjWeight = sj.subtract(bigDecimal1);
                allotManagement.setAllotActual(sjWeight.doubleValue());
                allotManagement.setAllotAmountIn(allotManagement.getAllotWeightOut());
            } else if ("3".equals(publicGoods.getMaterialUnit())) {
                BigDecimal sj = new BigDecimal(String.valueOf(allotManagement.getAllotActual()));
                BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(allotManagementDetail.getNetWeight())).divide(new BigDecimal("1000"));
                BigDecimal sjWeight = sj.subtract(bigDecimal1);
                allotManagement.setAllotActual(sjWeight.doubleValue());
                allotManagement.setAllotAmountIn(sjWeight.doubleValue());
            } else {
                BigDecimal sj = new BigDecimal(String.valueOf(allotManagement.getAllotActual()));
                BigDecimal bigDecimal1 = new BigDecimal(1);
                BigDecimal sjWeight = sj.subtract(bigDecimal1);
                allotManagement.setAllotActual(sjWeight.doubleValue());
                allotManagement.setAllotAmountIn(Double.valueOf(allotManagement.getAllotNumOut()));
            }


            int i = allotManagementMapper.updateById(allotManagement);
            if (i <= 0) {
                throw new GlobalException("撤销失败");
            }

            //删除品质检验单
            allotDbDto.setCode("200");
            allotDbDto.setMessage("物料号码:" + allotDbVo.getMaterialNumber() + "净重:" + wmsStockInfo.getWsiNetWeight() + "数量:" + 1 + "撤销成功");
        }

        return allotDbDto;
    }

    /**
     * 调拨入库
     *
     * @param allotDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AllotDbDto inAllot(AllotDbVo allotDbVo) {
        String type = allotDbVo.getType();
        String step = allotDbVo.getStep();

        AllotDbDto allotDbDto = new AllotDbDto();

        //获取菜单id
        Long menuId = feignService.getIdByMenuName("调拨管理");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        if (sysDocument.getDocCode() == null) {
            allotDbDto.setMessage("未进行单据配置");
            allotDbDto.setCode("500");
            return allotDbDto;
        }

        //根据字典查出单位
        List<SysDictData> unitList = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        AllotManagement byId = getById(allotDbVo.getId());

        if (byId.getAllotStatus() != 3 && byId.getAllotStatus() != 4) {
            throw new GlobalException("只能对待入库或者入库中状态的单据进行出库");
        }

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, byId.getAllotItemCode()));

        //扫码入库
        if ("1".equals(type)) {
            if ("1".equals(step)) {
                //关联库位信息

                WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(allotDbVo.getMaterialNumber());

                allotDbDto.setStockInfo(warehouseCode.getCombinationName());
                allotDbDto.setCkId(warehouseCode.getCkId());
                allotDbDto.setKqId(warehouseCode.getKqId());
                allotDbDto.setKwId(warehouseCode.getKwId());

                if (warehouseCode.getCombinationName() == null) {
                    allotDbDto.setCode("500");
                    allotDbDto.setMessage("请输入正确的库位编码");
                    return allotDbDto;
                }

                allotDbDto.setCode("200");
                allotDbDto.setMessage("请输入物料号码");

            } else if ("2".equals(step)) {
                String stockInfo = allotDbVo.getStockInfo();
                if (stockInfo == "" || stockInfo == null) {
                    allotDbDto.setMessage("请先关联库位");
                    allotDbDto.setCode("500");
                    return allotDbDto;
                }
                //查询当前号码是否在明细表中
                AllotManagementDetail allotManagementDetail = allotManagementDetailMapper.selectOne(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getAllotDoc, byId.getAllotDoc()));
                if (allotManagementDetail == null) {
                    allotDbDto.setMessage("扫描失败，请核实后扫描");
                    allotDbDto.setCode("500");
                    return allotDbDto;
                }
                //修改物料为在库
                WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotDbVo.getMaterialNumber()).eq(WmsStockInfo::getWsiMaterialStatus, 3));

                if (wmsStockInfo == null) {
                    allotDbDto.setCode("500");
                    allotDbDto.setMessage("请勿重复扫码");
                    return allotDbDto;
                }

                //修改为在库
                wmsStockInfo.setWsiMaterialStatus(2);

                wmsStockInfo.setWsiWarehourse(allotDbVo.getCkId() + "");
                wmsStockInfo.setWsiReservoirArea(allotDbVo.getKqId() + "");
                wmsStockInfo.setWsiStorageLoaction(allotDbVo.getKwId() + "");
                wmsStockInfo.setWsiWarehourseInfo(stockInfo);

                wmsStockInfoMapper.updateById(wmsStockInfo);

                AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());
                //修改单据状态为入库中,添加入库重量/入库数量
                allotManagement.setAllotStatus(4);

                Double allotWeightIn = allotManagement.getAllotWeightIn();

                if (allotWeightIn == null) {
                    allotWeightIn = 0.0;
                }

                BigDecimal bigDecimal = new BigDecimal(String.valueOf(allotWeightIn));


                BigDecimal bigDecimal1 = new BigDecimal(wmsStockInfo.getWsiNetWeight());
                BigDecimal add = bigDecimal.add(bigDecimal1);

                allotManagement.setAllotWeightIn(add.doubleValue());

                Integer allotNumIn = allotManagement.getAllotNumIn();
                if (allotNumIn == null) {
                    allotNumIn = 0;
                }
                allotManagement.setAllotNumIn(allotNumIn + 1);

                allotManagementMapper.updateById(allotManagement);
                //修改物料明细为已入库
                allotManagementDetail.setMaterialStatus(2);

                //入库仓库
                allotManagementDetail.setInStorage(stockInfo);
                //入库人
                allotManagementDetail.setDepositorIn(SecurityUtils.getUsername());
                //入库时间
                allotManagementDetail.setReviceTime(new Date());

                allotManagementDetailMapper.updateById(allotManagementDetail);

                AllotManagement allotManagement2 = allotManagementMapper.selectById(allotDbVo.getId());

                //判断单位是否是kg
                if ("2".equals(publicGoods.getMaterialUnit())) {
                    //实际量
                    allotManagement2.setAllotActual(allotManagement2.getAllotWeightIn());
                } else if ("3".equals(publicGoods.getMaterialUnit())) {
                    //实际量
                    BigDecimal dun = new BigDecimal("1000");
                    BigDecimal outNum = new BigDecimal(String.valueOf(allotManagement2.getAllotWeightIn()));
                    BigDecimal divide = outNum.divide(dun);
                    //实际量
                    allotManagement2.setAllotActual(divide.doubleValue());
                } else {
                    //实际量
                    allotManagement2.setAllotActual(Double.parseDouble(allotManagement2.getAllotNumIn() + ""));
                }
                updateById(allotManagement2);

                //入库数量
                allotDbDto.setAllotNumOut(allotManagement2.getAllotNumIn());

                //入库计划量/实际量
                allotDbDto.setPlanActual(allotManagement2.getAllotAmountIn() + "/" + allotManagement2.getAllotActual() + unitMap.get(publicGoods.getMaterialUnit()));
                //提示
                allotDbDto.setMessage("物料号码:" + allotDbVo.getMaterialNumber() + "净重:" + wmsStockInfo.getWsiNetWeight() + "数量:1,录入成功");


                //查出调拨信息单
                AllotManagement allotManagement1 = allotManagementMapper.selectById(allotDbVo.getId());
                //判断是否有超收
                int docHairMark = sysDocument.getDocExcessMark();
                //没有超发
                if (docHairMark != 1 && publicGoods.getMaterialClosed() != 1) {

                    //如果是kg
                    if ("2".equals(publicGoods.getMaterialUnit()) || "3".equals(publicGoods.getMaterialUnit())) {
                        //计划出库重量
                        Double allotAmount = allotManagement1.getAllotAmount();
                        //实际出库重量
                        Double allotWeightOut = allotManagement1.getAllotWeightOut();
                        if (allotWeightOut >= allotAmount) {

                            //修改单据状态为已完成
                            allotManagement1.setAllotStatus(5);
                            allotManagementMapper.updateById(allotManagement1);
                        }
                    } else {
                        //计划出库重量
                        double allotAmount = allotManagement1.getAllotAmount();
                        //实际出库数量
                        double allotNumOut = Double.parseDouble(String.valueOf(allotManagement1.getAllotNumOut()));
                        if (allotNumOut >= allotAmount) {
                            //修改单据状态为已完成
                            allotManagement1.setAllotStatus(5);

                            allotManagementMapper.updateById(allotManagement1);

                        }

                    }
                }

            }
        } else if ("2".equals(type)) {
            if ("1".equals(step)) {
                //关联库位信息
                WarehouseStringDto warehouseCode = warehouseService.getWarehouseCode(allotDbVo.getMaterialNumber());

                allotDbDto.setStockInfo(warehouseCode.getCombinationName());
                allotDbDto.setCkId(warehouseCode.getCkId());
                allotDbDto.setKqId(warehouseCode.getKqId());
                allotDbDto.setKwId(warehouseCode.getKwId());
                allotDbDto.setMessage("操作成功");

            } else if ("2".equals(step)) {
                //查询当前批次是否在物料明细
                String stockInfo = allotDbVo.getStockInfo();
                if (stockInfo == "" || stockInfo == null) {
                    allotDbDto.setMessage("请先关联库位");
                    allotDbDto.setCode("500");
                    return allotDbDto;
                }
                //查询当前批次是否在物料明细中
                //查询当前号码是否在明细表中
                List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialBatch, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getAllotDoc, byId.getAllotDoc()));
                if (allotManagementDetailList == null) {
                    allotDbDto.setMessage("扫描失败，请核实后扫描");
                    allotDbDto.setCode("500");
                    return allotDbDto;
                }

                Double netWeight = wmsStockInfoMapper.getNetWeight(allotDbVo.getMaterialNumber());

                List<WmsStockInfo> wmsStockInfoList = new ArrayList<>();

                for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                    //修改物料为在库
                    WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotManagementDetail.getMaterialNumber()));
                    //修改为在库
                    wmsStockInfo.setWsiMaterialStatus(2);
                    //修改库区，库位，仓库，仓储信息

                    wmsStockInfo.setWsiWarehourse(allotDbVo.getCkId() + "");
                    wmsStockInfo.setWsiReservoirArea(allotDbVo.getKqId() + "");
                    wmsStockInfo.setWsiStorageLoaction(allotDbVo.getKwId() + "");
                    wmsStockInfo.setWsiWarehourseInfo(stockInfo);

                    wmsStockInfoList.add(wmsStockInfo);


                    AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());
                    //修改单据状态为入库中,添加入库重量
                    allotManagement.setAllotStatus(4);
                    Integer allotNumIn = allotManagement.getAllotNumIn();

                    if (allotNumIn == null) {
                        allotNumIn = 0;
                    }

                    allotManagement.setAllotNumIn(allotNumIn + 1);

                    Double allotWeightIn = allotManagement.getAllotWeightIn();
                    if (allotWeightIn == null) {
                        allotWeightIn = 0.0;
                    }

                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(allotWeightIn));
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(wmsStockInfo.getWsiNetWeight()));
                    BigDecimal add = bigDecimal.add(bigDecimal1);
                    allotManagement.setAllotWeightIn(add.doubleValue());
                    allotManagementMapper.updateById(allotManagement);
                    //修改物料明细为已入库
                    allotManagementDetail.setMaterialStatus(2);

                    //入库仓库
                    allotManagementDetail.setInStorage(stockInfo);
                    //入库人
                    allotManagementDetail.setDepositorIn(SecurityUtils.getUsername());
                    //入库时间
                    allotManagementDetail.setReviceTime(new Date());

                    allotManagementDetailMapper.updateById(allotManagementDetail);

                }
                wmsStockInfoService.updateBatchById(wmsStockInfoList);
                //提示消息
                allotDbDto.setMessage("批次号:" + allotDbVo.getMaterialNumber() + "总净重:" + netWeight + "数量:" + allotManagementDetailList.size() + "录入成功");

                AllotManagement allotManagement2 = allotManagementMapper.selectById(allotDbVo.getId());

                //判断单位是否是kg
                if ("2".equals(publicGoods.getMaterialUnit())) {
                    //实际量
                    allotManagement2.setAllotActual(allotManagement2.getAllotWeightIn());
                } else if ("3".equals(publicGoods.getMaterialUnit())) {
                    //实际量
                    BigDecimal dun = new BigDecimal("1000");
                    BigDecimal outNum = new BigDecimal(String.valueOf(allotManagement2.getAllotWeightIn()));
                    BigDecimal divide = outNum.divide(dun);

                    //实际量
                    allotManagement2.setAllotActual(divide.doubleValue());
                } else {
                    //实际量
                    allotManagement2.setAllotActual(Double.parseDouble(allotManagement2.getAllotNumIn() + ""));
                }
                updateById(allotManagement2);

                //查询调拨单
                AllotManagement allotManagement = allotManagementMapper.selectById(allotDbVo.getId());

                //计划/实际重量
                allotDbDto.setPlanActual(allotManagement.getAllotWeightIn() + "/" + allotManagement.getAllotActual() + unitMap.get(publicGoods.getMaterialUnit()));
                //入库数量
                allotDbDto.setAllotNumOut(allotManagement.getAllotNumIn());

                //查出调拨信息单
                AllotManagement allotManagement1 = allotManagementMapper.selectById(allotDbVo.getId());
                //判断是否有超收
                int docHairMark = sysDocument.getDocExcessMark();
                //超发
                if (docHairMark != 1 && publicGoods.getMaterialClosed() != 1) {

                    //如果是kg
                    if ("2".equals(allotManagement1.getAllotUnit()) || "3".equals(allotManagement1.getAllotUnit())) {
                        //计划出库重量
                        Double allotAmount = allotManagement1.getAllotAmount();
                        //实际出库重量
                        Double allotWeightOut = allotManagement1.getAllotWeightOut();
                        if (allotWeightOut >= allotAmount) {

                            //修改单据状态为已完成
                            allotManagement1.setAllotStatus(5);
                            allotManagementMapper.updateById(allotManagement1);

                        }
                    } else {
                        //计划出库重量
                        double allotAmount = allotManagement1.getAllotAmount();

                        //实际出库数量
                        double allotNumOut = Double.parseDouble(String.valueOf(allotManagement1.getAllotNumOut()));
                        if (allotNumOut >= allotAmount) {
                            //修改单据状态为待入库
                            allotManagement1.setAllotStatus(5);
                            allotManagementMapper.updateById(allotManagement1);
                        }

                    }
                }
            }
        } else if ("3".equals(type)) {

            //修改物料明细状态为已出库
            AllotManagementDetail allotManagementDetail = allotManagementDetailMapper.selectOne(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, allotDbVo.getMaterialNumber()).eq(AllotManagementDetail::getMaterialStatus, 2).eq(AllotManagementDetail::getAllotDoc, byId.getAllotDoc()));
            if (allotManagementDetail == null) {
                allotDbDto.setMessage("撤销失败");
                allotDbDto.setCode("500");
                return allotDbDto;
            }
            allotManagementDetail.setMaterialStatus(1);
            allotManagementDetailMapper.updateById(allotManagementDetail);
            //把仓库的库区信息等清空
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotDbVo.getMaterialNumber()));
            wmsStockInfo.setWsiWarehourseInfo("");
            wmsStockInfo.setWsiWarehourse("");
            wmsStockInfo.setWsiReservoirArea("");
            wmsStockInfo.setWsiStorageLoaction("");
            wmsStockInfoMapper.updateById(wmsStockInfo);

            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.set("in_storage", null);
            updateWrapper.set("revice_time", null);
            updateWrapper.set("depositor_in", null);
            updateWrapper.eq("material_number", allotManagementDetail.getMaterialNumber());
            updateWrapper.eq("allot_doc", allotManagementDetail.getAllotDoc());
            allotManagementDetailService.update(updateWrapper);

            allotDbDto.setMessage("物料号码:" + allotDbVo.getMaterialNumber() + ",净重:" + allotManagementDetail.getNetWeight() + "数量:1,解绑成功");
        }
        allotDbDto.setCode("200");
        return allotDbDto;
    }


    /**
     * 拣货完成出库
     *
     * @param id
     * @return
     */
    @Override
    public boolean finishAllot(Long id) throws Exception {
        //判断当前页面是否有配置送检和交接，如果有则生成品检单


        //获取菜单id
        Long menuId = feignService.getIdByMenuName("调拨管理");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);

        //查出调拨信息单
        AllotManagement allotManagement = allotManagementMapper.selectById(id);

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, allotManagement.getAllotItemCode()));


        //判断是否有检验
        int docInspectionMark = sysDocument.getDocInspectionMark();
        //如果有检验
        if (docInspectionMark == 1) {

            //生成品质检验单
            QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
            //添加类别，编码，物料类别
            qualityInspectionDocumentVo.setMaterialCode(allotManagement.getAllotItemCode());
            qualityInspectionDocumentVo.setMaterialCategory(publicGoods.getMaterialType());
            qualityInspectionDocumentVo.setCategory(publicGoods.getMaterialCategory());
            qualityInspectionDocumentVo.setAssociatedNo(allotManagement.getAllotDoc());
            qualityInspectionDocumentVo.setModeType(8);
            List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNoVos = new ArrayList<>();
            //查询当前明细表中的所有物料号码
            List<AllotManagementDetail> allotManagementDetails = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

            String batchNum = "";

            for (int j = 0; j < allotManagementDetails.size(); j++) {
                if (j == 0) {
                    batchNum = allotManagementDetails.get(j).getMaterialBatch();
                } else {
                    if (!batchNum.equals(allotManagementDetails.get(j).getMaterialBatch())) {
                        batchNum = batchNum + "," + allotManagementDetails.get(j).getMaterialBatch();
                    }
                }

                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                materialNumberAndBatchNoVo.setMaterialNumber(allotManagementDetails.get(j).getMaterialNumber());
                materialNumberAndBatchNoVo.setBatchNo(allotManagementDetails.get(j).getMaterialBatch());
                materialNumberAndBatchNoVo.setMaterialCategory(publicGoods.getMaterialCategory());
                materialNumberAndBatchNoVos.add(materialNumberAndBatchNoVo);
            }
            qualityInspectionDocumentVo.setBatchNo(batchNum);

            productionPickingService.insertQuality(sysDocument, qualityInspectionDocumentVo, materialNumberAndBatchNoVos);
            //修改单据状态为待检验
            allotManagement.setAllotStatus(6);
            return allotManagementMapper.updateById(allotManagement) > 0;
        }

        //判断是否有交接
        int docHandoverMark = sysDocument.getDocHandoverMark();
        //有交接
        if (docHandoverMark == 1) {
            //修改单据状态为待交接
            allotManagement.setAllotStatus(7);
            return allotManagementMapper.updateById(allotManagement) > 0;
        }

        /*
        //判断是否有超收
        int docHairMark = sysDocument.getDocHairMark();
        //超收
        if (docHairMark==1){*/
        //修改单据状态为待入库
        allotManagement.setAllotStatus(3);
        return allotManagementMapper.updateById(allotManagement) > 0;

    }


    /**
     * 拣货完成入库
     *
     * @param id
     * @return
     */
    @Override
    public boolean finishAllotIn(Long id) {
        //获取菜单id
        /*
        Long menuId = feignService.getIdByMenuName("调拨管理");
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        */
        //查出调拨信息单
        AllotManagement allotManagement = allotManagementMapper.selectById(id);

        /*
        //判断是否有超收
        int docHairMark = sysDocument.getDocHairMark();
        //超收
        if (docHairMark==1){

         */
        //修改单据状态为完成
        allotManagement.setAllotStatus(5);
        return allotManagementMapper.updateById(allotManagement) > 0;
            /*
        }else{
            return true;
        }
        */

    }


    /**
     * 拣货撤销
     *
     * @param id
     * @return
     */
    @Override
    public boolean repealAllot(Long id) {
        //修改单据状态为待出库
        AllotManagement allotManagement = allotManagementMapper.selectById(id);
        allotManagement.setAllotStatus(1);
        //重量扣除，数量清空
        allotManagement.setAllotWeightIn(0.0);
        allotManagement.setAllotNumIn(0);
        allotManagement.setAllotActual(0.0);
        //交接数量清空
        allotManagement.setAllotNumOut(0);
        //交接重量清空
        allotManagement.setOverWeight(0.0);
        allotManagementMapper.updateById(allotManagement);

        List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
        for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
            //修改仓库状态为在库
            WmsStockInfo wmsStockInfo = wmsStockInfoMapper.selectOne(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialNumber, allotManagementDetail.getMaterialNumber()));
            wmsStockInfo.setWsiMaterialStatus(2);
            wmsStockInfoMapper.updateById(wmsStockInfo);
        }
        //删除所有明细
        boolean remove = allotManagementDetailService.remove(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

        return remove;
    }

    /**
     * 交接
     *
     * @param pickingRestDbVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PickingRestHandoverDto overAllot(PickingRestDbVo pickingRestDbVo) {
        //获取步骤
        int step = pickingRestDbVo.getExecutionOrder();
        //返回值
        PickingRestHandoverDto pickingRestHandoverDto = new PickingRestHandoverDto();
        //获取菜单id
        Long menuId = feignService.getIdByMenuName("调拨管理");
        //交接方式
        AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
        SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
        //拿到交接方式
        int jjType = sysDocument.getDocHandoverMethod();

        AllotManagement byId = getById(pickingRestDbVo.getId());
        //根据字典查出单位
        List<SysDictData> unitList = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, byId.getAllotItemCode()));

        if (step == 1) {


            //校验员工编号
            AjaxResult byUserName = remoteUserService.getByUserName(pickingRestDbVo.getInputValue());
            SysUser userInfo = JSON.parseObject(JSON.toJSONString(byUserName.get("data")), SysUser.class);

            if (userInfo.getUserName() == null) {
                pickingRestHandoverDto.setResultCode("500");
                pickingRestHandoverDto.setMessage("交接人输入有误,请核对后输入");
                return pickingRestHandoverDto;
            }

            //返回交接人
            pickingRestHandoverDto.setHandoverName(userInfo.getUserName() + "-" + userInfo.getNickName());
            pickingRestHandoverDto.setDocHandoverMethod(jjType);


            if (jjType == 1) {
                pickingRestHandoverDto.setMessage("请输入物料条码");
            } else if (jjType == 2) {
                pickingRestHandoverDto.setMessage("请输入批次号");
            } else if (jjType == 3) {
                AllotManagement allotManagement = allotManagementMapper.selectById(pickingRestDbVo.getId());
                pickingRestDbVo.setInputValue(allotManagement.getAllotDoc());
                //判断是否存在明细表中
                List<AllotManagementDetail> allotManagementDetailList11 = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, pickingRestDbVo.getInputValue()));
                if (allotManagementDetailList11 == null) {
                    throw new GlobalException("交接失败");
                }

                //查询当前单据号在明细中是否存在，且状态为待交接
                List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getMaterialStatus, 3));
                if (allotManagementDetailList.size() == 0) {
                    pickingRestHandoverDto.setMessage("交接失败,请核实后再录入");
                    return pickingRestHandoverDto;
                } else {
                    //查出当前为待交接状态的单据明细,算出总净重和总数量
                    Double sumPiHao = allotManagementDetailMapper.getDoc(pickingRestDbVo.getInputValue());
                    //总数量
                    long sumNum = allotManagementDetailMapper.selectCount(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getAllotDoc, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getMaterialStatus, 3));

                    //计划重量
                    Double allotAmount = allotManagement.getAllotAmount();

                    //返回计划/实际
                    //判断是否是kg
                    //(实际交接)
                    Double overWe = allotManagement.getOverWeight();
                    if (overWe == null) {
                        overWe = 0.00;
                    }
                    BigDecimal bigDecimal = new BigDecimal(overWe);
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(sumPiHao);
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    allotManagement.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitMap.get(publicGoods.getMaterialUnit()));


                    //保存交接数量，交接重量
                    Integer overNum = allotManagement.getOverNum();
                    if (overNum == null) {
                        overNum = 0;
                    }
                    int jjSum = (int) sumNum;
                    allotManagement.setOverNum(overNum + jjSum);

                    //取出关节人
                    String closeUser = allotManagement.getCloseUser();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = SecurityUtils.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        allotManagement.setCloseUser(name);
                    }

                    if (jj == 1) {
                        if (closeUser == null || "".equals(closeUser)) {
                            allotManagement.setCloseUser(name);
                        } else {
                            allotManagement.setCloseUser("," + name);
                        }
                    }

                    allotManagement.setCloseTime(new Date());


                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(allotManagement.getAllotNumOut() + "/" + allotManagement.getOverNum());

                    for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                        //修改物料状态明细为已出库
                        allotManagementDetail.setMaterialStatus(1);
                        allotManagementDetailMapper.updateById(allotManagementDetail);
                    }


                    //判断是否所有物料没有待交接的状态
                    List<AllotManagementDetail> allotManagementDetailList1 = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialStatus, 3).eq(AllotManagementDetail::getAllotDoc, pickingRestDbVo.getInputValue()));

                    if (allotManagementDetailList1.size() == 0) {
                        //修改单据状态为待入库
                        allotManagement.setAllotStatus(3);

                    }
                    boolean b = updateById(allotManagement);
                    if (!b) {
                        throw new GlobalException("交接失败");
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("单据号:" + pickingRestDbVo.getInputValue() + ",总净重" + sumPiHao + "数量:" + sumNum + ",交接成功");
                }
            }
            pickingRestHandoverDto.setResultCode("200");
            return pickingRestHandoverDto;

        } else if (step == 2) {
            if (jjType == 1) {
                AllotManagement allotManagement = allotManagementMapper.selectById(pickingRestDbVo.getId());

                //判断是否存在明细表中
                List<AllotManagementDetail> allotManagementDetailList11 = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
                if (allotManagementDetailList11 == null) {
                    throw new GlobalException("交接失败");
                }

                //判断当前物料是否存在且属于待交接
                AllotManagementDetail allotManagementDetail = allotManagementDetailMapper.selectOne(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialNumber, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getMaterialStatus, 3).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
                if (allotManagementDetail == null) {
                    pickingRestHandoverDto.setMessage("不可重复交接");
                    return pickingRestHandoverDto;
                } else {
                    //入库重量
                    Double allotAmount = allotManagement.getAllotAmount();

                    if (allotAmount == null) {
                        allotAmount = 0.0;
                    }

                    //(实际交接)
                    Double overWeight = allotManagement.getOverWeight();
                    if (overWeight == null) {
                        overWeight = 0.0;
                    }
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(overWeight));
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(allotManagementDetail.getNetWeight()));
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    allotManagement.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitMap.get(publicGoods.getMaterialUnit()));

                    Integer overNum = allotManagement.getOverNum();
                    if (overNum == null) {
                        overNum = 0;
                    }

                    //保存交接数量，交接重量
                    allotManagement.setOverNum(overNum + 1);

                    //取出关节人
                    String closeUser = allotManagement.getCloseUser();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = SecurityUtils.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        allotManagement.setCloseUser(name);
                    }

                    if (jj == 1) {
                        if (closeUser == null || "".equals(closeUser)) {
                            allotManagement.setCloseUser(name);
                        } else {
                            allotManagement.setCloseUser("," + name);
                        }
                    }

                    allotManagement.setCloseTime(new Date());


                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(allotManagement.getAllotNumOut() + "/" + allotManagement.getOverNum());

                    //修改物料状态明细为已出库
                    allotManagementDetail.setMaterialStatus(1);
                    allotManagementDetailMapper.updateById(allotManagementDetail);


                    //判断是否所有物料没有待交接的状态
                    List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialStatus, 3).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
                    if (allotManagementDetailList.size() == 0) {
                        //修改单据状态为待入库
                        allotManagement.setAllotStatus(3);

                    }
                    boolean b = updateById(allotManagement);
                    if (!b) {
                        throw new GlobalException("交接失败");
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("物料号码:" + pickingRestDbVo.getInputValue() + ",净重" + allotManagementDetail.getNetWeight() + "数量:1,交接成功");
                    pickingRestHandoverDto.setResultCode("200");
                    return pickingRestHandoverDto;
                }
            } else if (jjType == 2) {
                AllotManagement allotManagement = allotManagementMapper.selectById(pickingRestDbVo.getId());

                //判断是否存在明细表中
                List<AllotManagementDetail> allotManagementDetailList11 = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialBatch, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
                if (allotManagementDetailList11 == null) {
                    throw new GlobalException("交接失败");
                }

                //查询当前批号在明细中是否存在，且状态为待交接
                List<AllotManagementDetail> allotManagementDetailList = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialBatch, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getMaterialStatus, 3).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));
                if (allotManagementDetailList.size() == 0) {
                    pickingRestHandoverDto.setMessage("不可重复交接");
                    return pickingRestHandoverDto;
                } else {
                    //查出当前为待交接状态的批次，算出总净重和总数量
                    Double sumPiHao = allotManagementDetailMapper.getPiHao(pickingRestDbVo.getInputValue());

                    if (sumPiHao == null) {
                        sumPiHao = 0.0;
                    }

                    //总数量
                    long sumNum = allotManagementDetailMapper.selectCount(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialBatch, pickingRestDbVo.getInputValue()).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                    //计划重量
                    Double allotAmount = allotManagement.getAllotAmount();

                    //返回计划/实际
                    //判断是否是kg

                    //(实际交接)
                    Double overWeight = allotManagement.getOverWeight();
                    if (overWeight == null) {
                        overWeight = 0.0;
                    }
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(overWeight));
                    //查询号码在明细中的重量
                    BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(sumPiHao));
                    BigDecimal add = bigDecimal.add(bigDecimal1);

                    allotManagement.setOverWeight(add.doubleValue());

                    pickingRestHandoverDto.setQuantityIdentification(allotAmount + "/" + add.toString() + unitMap.get(publicGoods.getMaterialUnit()));


                    //保存交接数量，交接重量
                    int overNum = allotManagement.getOverNum();
                    int jjSum = (int) sumNum;
                    allotManagement.setOverNum(overNum + jjSum);

                    //取出关节人
                    String closeUser = allotManagement.getCloseUser();
                    if (closeUser == null) {
                        closeUser = "";
                    }
                    String[] split = closeUser.split(",");

                    //获取交接人名称
                    String name = SecurityUtils.getUsername();

                    //定义变量记录交接人是否相等
                    int jj = 0;

                    if (closeUser != null && !"".equals(closeUser)) {
                        for (String s : split) {
                            if (!name.equals(s)) {
                                jj = 1;
                            }
                        }
                    } else {
                        allotManagement.setCloseUser(name);
                    }

                    if (jj == 1) {
                        if (closeUser == null || "".equals(closeUser)) {
                            allotManagement.setCloseUser(name);
                        } else {
                            allotManagement.setCloseUser("," + name);
                        }
                    }

                    allotManagement.setCloseTime(new Date());
                    //出库/交接
                    pickingRestHandoverDto.setOutHandoverActual(allotManagement.getAllotNumOut() + "/" + allotManagement.getOverNum());

                    for (AllotManagementDetail allotManagementDetail : allotManagementDetailList) {
                        //修改物料状态明细为已出库
                        allotManagementDetail.setMaterialStatus(1);
                        allotManagementDetailMapper.updateById(allotManagementDetail);
                    }


                    //判断是否所有物料没有待交接的状态
                    List<AllotManagementDetail> allotManagementDetailList1 = allotManagementDetailMapper.selectList(new QueryWrapper<AllotManagementDetail>().lambda().eq(AllotManagementDetail::getMaterialStatus, 3).eq(AllotManagementDetail::getAllotDoc, allotManagement.getAllotDoc()));

                    if (allotManagementDetailList1.size() == 0) {
                        //修改单据状态为待入库
                        allotManagement.setAllotStatus(3);

                    }
                    boolean b = updateById(allotManagement);
                    if (!b) {
                        throw new GlobalException("交接失败");
                    }

                    //消息提示
                    pickingRestHandoverDto.setMessage("批次号:" + pickingRestDbVo.getInputValue() + ",总净重" + sumPiHao + "数量:" + sumNum + ",交接成功");
                    pickingRestHandoverDto.setResultCode("200");
                    return pickingRestHandoverDto;
                }
            } else if (jjType == 3) {
                pickingRestHandoverDto.setMessage("请勿重复交接");
                pickingRestHandoverDto.setResultCode("500");
            }

        }
        return pickingRestHandoverDto;
    }


}